<?php

namespace App\Services\Traits;

use Helper\Timed;

trait DatabaseMysql
{

    /**
     * 制作排序参数
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param string $order
     * @return $this
     */
    protected function makeOrderParam($request, $query, $column = null, $order = null)
    {
        $query->orderBy($column ?: $request->input('order_column', 'id'), $order ?: $request->input('order', 'desc'));

        return $this;
    }

    /**
     * 制作分页参数
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return $this
     */
    protected function makePaginationParam($request, $query)
    {
        $query->offset(($this->getPage($request) - 1) * $this->getPageSize($request))->limit($this->getPageSize($request));

        return $this;
    }

    /**
     * 制作查询
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param mixed $value
     * @param string $operator
     * @return $this
     */
    protected function makeWhere($query, $column = null, $value = null, $operator = '=')
    {
        $column = str_replace('.', '->', $column);

        if (is_array($value)) {
            $query->whereIn($column, $value);
        } else {
            $query->where($column, $operator, $value);
        }

        return $this;
    }

    /**
     * 制作查询【排除】
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param mixed $value
     * @param string $operator
     * @return $this
     */
    protected function makeWhereNot($query, $column = null, $value = null, $operator = '!=')
    {
        $column = str_replace('.', '->', $column);

        if (is_array($value)) {
            $query->whereNotIn($column, $value);
        } else {
            $query->where($column, $operator, $value);
        }

        return $this;
    }

    /**
     * 制作查询参数
     *
     * @param \Illuminate\Http\Request $request
     * @param string $key
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param string $operator
     * @return $this
     */
    protected function makeWhereParam($request, $key, $query, $column = null, $operator = '=')
    {
        if ($this->isValidParam($request, $key)) {
            $this->makeWhere($query, $column ?: $key, $this->getParam($request, $key), $operator);
        }
        return $this;
    }

    /**
     * 制作查询参数【排除】
     *
     * @param \Illuminate\Http\Request $request
     * @param string $key
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param string $operator
     * @return $this
     */
    protected function makeWhereParamNot($request, $key, $query, $column = null, $operator = '!=')
    {
        if ($this->isValidParam($request, $key)) {
            $this->makeWhereNot($query, $column ?: $key, $this->getParam($request, $key), $operator);
        }
        return $this;
    }

    /**
     * 制作查询参数【like】
     *
     * @param \Illuminate\Http\Request $request
     * @param string $key
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param boolean $isLeft
     * @return $this
     */
    protected function makeWhereParamLike($request, $key, $query, $column = null, $isLeft = true)
    {
        if ($this->isValidParam($request, $key)) {
            $query->where($column ?: $key, 'like', ($isLeft ? '' : '%') . $request->input($key) . '%');
        }
        return $this;
    }

    /**
     * 制作查询参数【搜索】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param string $key
     * @return $this
     */
    protected function makeWhereParamSearch($request, $query, $column = null, $key = 'keyword')
    {
        if ($this->isValidParam($request, $key)) {

            $column = $column ?: $request->input('keyword_column', 'id');

            $this->makeWhereParam($request, $key, $query, $column);
        }
        return $this;
    }

    /**
     * 制作查询参数【datetime】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param string $key
     * @return $this
     */
    protected function makeWhereParamDatetime($request, $query, $column = null, $key = 'datetime')
    {
        if ($this->isValidParam($request, $key)) {

            $datetime = $this->getParamArray($request, $key);

            $column = $column ?: $request->input('datetime_column', 'created');

            $query->where($column, '>=', $datetime[0])->where($column, '<=', $datetime[1]);
        }
        return $this;
    }

    /**
     * 制作查询参数【二进制位】
     *
     * @param \Illuminate\Http\Request $request
     * @param string $key
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @return $this
     */
    protected function makeWhereParamBits($request, $key, $query, $column = null)
    {
        if ($this->isValidParam($request, $key)) {

            $bits = $this->getParamArray($request, $key);

            $column = $column ?: $key;

            $query->where(function ($query) use ($bits, $column) {
                $query->where($column, '&', array_shift($bits));
                foreach ($bits as $bit) {
                    $query->orWhere($column, '&', $bit);
                }
            });
        }
        return $this;
    }

    /**
     * 制作查询参数【最近n天】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param int $days
     * @return $this
     */
    protected function makeWhereLastDays($request, $query, $column = null, $days = 30)
    {
        $request->offsetSet('datetime', [Timed::getTodayTimed() - 86400 * ($days - 1), Timed::getDayNextTimed() - 1]);

        $this->makeWhereParamDatetime($request, $query, $column, 'datetime');

        return $this;
    }

    /**
     * 制作查询参数【软删除】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return $this
     */
    protected function makeWhereDeleted($request, $query)
    {
        // 软删除筛选
        if (!$this->isValidParam($request, 'deleted')) {
            $query->withTrashed();
        } elseif ((boolean)$request->input('deleted')) {
            $query->onlyTrashed();
        }
        return $this;
    }

    /**
     * 制作查询参数【平台】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @return $this
     */
    protected function makeWhereOrg($request, $query, $column = 'plat_code')
    {
        if (!$request->user()->isSuperAdmin()) {
            $query->whereIn($column, $request->user()->getTreePermissionOrgs()->pluck('code')->toArray());
        }
        return $this;
    }

    /**
     * 制作查询参数【平台】【默认值】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $column
     * @param string $key
     * @return $this
     */
    protected function makeWhereParamOrg($request, $query, $column = 'plat_code', $key = 'plat_code')
    {
        if ($this->isValidParam($request, $key)) {
            $this->makeWhere($query, $column, $this->getParam($request, $key));
        } else {
            $this->makeWhereOrg($request, $query, $column);
        }
        return $this;
    }

    /**
     * 制作查询参数【自定义字段范围筛选】
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $key
     * @return $this
     */
    protected function makeWhereFieldRange($request, $query, $key = 'fieldRange')
    {
        if ($this->isValidParam($request, $key)) {
            $option = $this->getParamArray($request, $key);

            if (empty($option['field'])) {
                return $this;
            }

            if (isset($option['min']) && !is_bool($option['min']) && trim((string)$option['min']) !== '') {
                $this->makeWhere($query, $option['field'], $option['min'], '>=');
            }

            if (isset($option['max']) && !is_bool($option['max']) && trim((string)$option['max']) !== '') {
                $this->makeWhere($query, $option['field'], $option['max'], '<=');
            }
        }
        return $this;
    }
}
